const fs = require('fs');
const path = require('path');

function getRtfImages(text, context) {
	let regexPictureHeader = /{\\pict[\s\S]+?\\bliptag-?\d+(\\blipupi-?\d+)?({\\\*\\blipuid\s?[\da-fA-F]+)?[\s}]*?/;
	let regexPicture = new RegExp(`(?:(${regexPictureHeader.source}))([\\da-fA-F\\s]+)\\}`, 'g');
	let images = text.match(regexPicture);
	if (!images) {
		// for wps
		regexPictureHeader = /{\\pict[\s\S]+?(\\pngblip-?\d+)?(\\wmetafile8-?\d+)?{\\\*\\blipuid\s?[\da-fA-F]+[\s}]*?/;
		regexPicture = new RegExp(`(?:(${regexPictureHeader.source}))([\\da-fA-F\\s]+)\\}`, 'g');
		images = text.match(regexPicture);
	}
	if (images) {
		for (const image of images) {
			let imageType;
			if (image.includes('\\pngblip')) {
				imageType = 'image/png';
			} else if (image.includes('\\jpegblip')) {
				imageType = 'image/jpeg';
			}
			if (imageType) {
				const hex = image.replace(regexPictureHeader, '').replace(/[^\da-fA-F]/g, '');
				// const base64 = `data:${imageType};base64,${hex2b64Ex(hex)}`;
				// context.images.push(base64);
				//const blob = hex2blob(hex, imageType);
				context.images.push(hex);
			}
		}
	}
}

function getRtfImages1(text, context) {
	const len = text.length;
	const regex = /\{\\pict\s+/g;
	let match = regex.exec(text);
	while (match) {
		let scan = match.index + match[0].length;
		let state = 0;
		let group = 0;
		let hexBegin = 0;
		let hexEnd = 0;
		let prop = '';
		let type = '';
		while (scan < len) {
			const c = text.charAt(scan++);
			if (state === 0) {
				if (c === '{') {
					state = 1;
					group++;
				} else if (c === '\\') {
					state = 2;
					prop = c;
				} else if (c === ' ' || c === '\\n' || c === '\\t') {
					// ignore space...
				} else {
					state = 3;
					hexBegin = scan - 1;
				}
			} else if (state === 1) {
				if (c === '}') {
					group--;
					if (group === 0) {
						state = 0;
					}
				} else if (c === '{') {
					group++;
				}
			} else if (state === 2) {
				if (c === ' ' || c === '\\n' || c === '\\t' || c === '}') {
					state = 0;
					if (prop === '\\jpegblip') {
						type = 'image/jpeg';
					} else if (prop === '\\pngblip') {
						type = 'image/png';
					}
				} else {
					prop += c;
				}
			} else {
				// state === 3
				if (/\s|\}/.test(c)) {
					hexEnd = scan - 1;
					state = 0;
					break;
				}
			}
		}
		if (type && hexEnd) {
			context.images.push(text.substring(hexBegin, hexEnd));
			regex.lastIndex = hexEnd;
			match = regex.exec(text);
		} else {
			match = regex.exec(text);
		}
	}
}

function getRtfImages2(text, context) {
	const arr = text.split(/{\\pict\s+/g);
	for (let i = 1; i < arr.length; i++) {
		const m = /(\\pngblip|\\jpegblip).*{\\\*\\blipuid\s*[\da-fA-F]+}\s*([\da-fA-F]+)/.exec(arr[i]);
		if (m) {
			context.images.push(m[2]);
		}
	}
}

function getRtfImages3(text, context) {
	const reg = /{\\pict.*?(\\pngblip|\\jpegblip).*?{\\\*\\blipuid\s*[\da-fA-F]+}\s*([\da-fA-F]+)/g;
	let m;
	while ((m = reg.exec(text))) {
		context.images.push(m[2]);
	}
}

const text = fs.readFileSync(path.join(__dirname, 'test.rtf'), 'utf8');
let context = { images: [] };

console.time('getRtfImages');
getRtfImages(text, context);
console.timeEnd('getRtfImages');
console.log(context.images.map((item) => item.length));

// context = { images: [] };
// console.time('getRtfImages1');
// getRtfImages1(text, context);
// console.timeEnd('getRtfImages1');

// context = { images: [] };
// console.time('getRtfImages2');
// getRtfImages2(text, context);
// console.timeEnd('getRtfImages2');

context = { images: [] };
console.time('getRtfImages3');
getRtfImages3(text, context);
console.timeEnd('getRtfImages3');

console.log(context.images.map((item) => item.length));
